package com.example.xcService.pojo.channels.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.example.pojo.response.CardInfo;
import com.example.xcService.pojo.channels.ChannelResult;
import com.example.xcService.pojo.channels.ChannelService;
import com.example.xcService.pojo.tool.HttpTool;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;

import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.nio.charset.StandardCharsets;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;
import java.util.*;

/**
 * 书亦官方接口
 * **/
@Slf4j
public class Plugin_ECARD_P012 implements ChannelService {
    public ChannelResult QueryBalance(JSONObject apiConfig){
        System.out.println("成功调用了QueryBalance");
        return  ChannelResult.success("success");
    }
    public  ChannelResult Submit(JSONObject apiConfig, Map<String,Object> data){

        try {

            JSONObject dataConfig= JSONObject.parseObject(JSONObject.toJSONString(data));

            JSONObject jsonObject = new JSONObject();
            jsonObject.put("jsonObject", apiConfig.getString("USERID"));
            jsonObject.put("projectId", dataConfig.getString("SUPProductId"));
            jsonObject.put("phone", dataConfig.getString("AccountVal"));
            jsonObject.put("outerOrderCode", dataConfig.getString("ChannelOrderCode"));
            String unencryptedContent = JSONObject.toJSONString(jsonObject);
            log.info("书亦请求参数："+unencryptedContent);

            String encryptedContent = segmentedEncryptByRsaPublicKeyStr(apiConfig.getString("SecretKey"), unencryptedContent);





            Map dataParams = new LinkedHashMap<String, String>();
            dataParams.put("channel",  apiConfig.getString("USERID"));
            dataParams.put("encryptedContent", encryptedContent);



            String url=apiConfig.getString("SubmitURL");

            String responseContent = HttpTool.sendPost(url, dataParams);
            JSONObject retobj = JSONObject.parseObject(responseContent);

            String code = retobj.getString("resultCode");
            String msg = retobj.getString("resultMsg");
            if (code.equals("0")) {
                JSONObject jsonData=retobj.getJSONObject("data");
                if (jsonData!=null){
                    JSONArray jsonArray=jsonData.getJSONArray("couponList");
                    if (jsonArray!=null && jsonArray.size()>0){

                        List<CardInfo> cardDataList=new ArrayList<>();
                        for (int i=0;i<jsonArray.size();i++){
                            JSONObject dataObj=jsonArray.getJSONObject(i);
                            CardInfo cardData=new CardInfo();
                            cardData.setType(0);
                            cardData.setCode(dataObj.getString("couponCode"));
                            cardData.setKey(dataObj.getString("couponCode"));
                            cardData.setEffstart(dataObj.getString("effectiveTime"));
                            cardData.setEffend(dataObj.getString("invalidTime"));
                            cardDataList.add(cardData);
                        }
                        return ChannelResult.success(cardDataList,"充值成功");
                    }
                }
                return ChannelResult.success("充值成功");
            }
            else if (code.equals("100000")){
                return ChannelResult.error("未知情况");
            }
            else {
                return ChannelResult.FAILED(code+","+msg);
            }
        }catch (Exception ex){
            ex.printStackTrace();
            log.error("书亦提交订单接口错误：",ex);
            return  ChannelResult.error("书亦提交订单接口错误");
        }
    }

    public  ChannelResult Query(JSONObject apiConfig,Map<String,Object> data) {
        return  ChannelResult.error("无查询接口");
    }


    public  ChannelResult Notify(JSONObject apiConfig,Map<String,Object> data){
        System.out.println("成功调用了Notify");
        return  ChannelResult.success("success");

    }

    /**
     * 得到RSA公钥
     *
     * @param publicKeyStr 公钥字符串
     * @return publicKey 公钥
     * @author 付聪
     * @time 2023/6/1 15:48
     */
    public static PublicKey getRsaPublicKey(String publicKeyStr) {


        PublicKey publicKey = null;
        try {
            byte[] keyBytes = Base64.getDecoder().decode(publicKeyStr.getBytes(StandardCharsets.UTF_8));
            X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
        } catch (Exception e) {
            log.error("执行【getRsaPublicKey】方法，出现异常，异常信息如下：", e);
        }

        return publicKey;

    }

    public static String segmentedEncryptByRsaPublicKeyStr(String publicKeyStr, String unencryptedContent) {


        // 已加密的内容
        String encryptedContent = null;
        try {


            byte[] tempByteArray = unencryptedContent.getBytes("UTF-8");
            PublicKey publicKey = getRsaPublicKey(publicKeyStr);
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            int inputLength = tempByteArray.length;
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            int offSet = 0;
            int i = 0;
            byte[] cache;

            while (inputLength - offSet > 0) {
                if (inputLength - offSet > 245) {
                    cache = cipher.doFinal(tempByteArray, offSet, 245);
                } else {
                    cache = cipher.doFinal(tempByteArray, offSet, inputLength - offSet);
                }
                out.write(cache, 0, cache.length);
                i++;
                offSet = i * 245;
            }

            byte[] encryptedContentByteArray = out.toByteArray();
            out.close();
            encryptedContent = Base64.getEncoder().encodeToString(encryptedContentByteArray);

        } catch (Exception e) {
            log.error("执行【segmentedEncryptByRsaPublicKeyStr】方法，出现异常，异常信息如下：", e);
        }

        return encryptedContent;

    }
}
